#include <stdio.h>
#include <stdlib.h> 
#include <string.h>
#include <dirent.h>

#define TRUE 1

char** wordSplit(char**, char*, char*);

int main(void)
{
	//directory struct
	struct dirent *de = NULL;
	DIR *d = NULL;
	//array of char arrays (they are going to be split up)
	char** words, **paths, **test;
	char* exeName, *exeName2, *env;
	pid_t processID;
	int processStatus, iter;
	env = getenv("PATH");
	//parse paths with regards to :
	paths = wordSplit(paths, env, ":");
	printf("%s\n", "Loesby and Nik's Shell Script");
	char buffer[256];	//If they need more than 256 characters, they need a different command
	char buffer2[256];
	while(TRUE)
	{
		char* pathName, *folderName;
		int pathLen, folderLen;
		printf("> ");//Print this every time to make our shell look pretty
		gets(buffer);//This prevents the while loop from just constantly printing '>'
		if(buffer[0] == '\0') continue;	//No command given
		/*
		split the command based on ' '
		this is for stuff like "mkdir foo"
		therefore words[0] will be the command and anything after that
		will be stuff we feed into the command
		*/
		words = wordSplit(words, buffer, " ");
		if(words[0] == NULL)//if nothing, just continue
			continue;
		exeName = words[0];//this is the executable command name at index 0
		int found = 0;//initializing the found flag
		if(words[0][0] == '/')//if the first character of the first "word" in the array is '/'...
		{	//...then they've given us an absolute path. We'll assume they input it correctly with/without .exe
			char* lastSlash = strrchr((const char*) exeName, '/');
			char* exeTemp = malloc((strlen(exeName) - strlen(lastSlash))*( sizeof(char)));
			folderName = malloc((lastSlash - exeName) * sizeof(char));
			strncpy(folderName, exeName, lastSlash - exeName);
			strncpy(exeTemp, exeName + (strlen(exeName) - strlen(lastSlash)) + sizeof(char), (strlen(exeName) - strlen(lastSlash)) - 1);
			d = opendir(folderName);
			if(d == NULL)
			{
				printf("File path invalid.\n");
				found = 0;
			}
			else//search
			{
				while(de = readdir(d))//iterating through folders
				{
					if(strcmp(de->d_name, exeTemp) == 0)//if you find it
					{
	
						pathName = malloc(strlen(folderName) + strlen(exeTemp) + sizeof(char));
						strcpy(pathName, folderName);
						strcat(pathName, "/");
						strcat(pathName, exeTemp);
						found = TRUE;
						break;
					}
				}
			}
		}
		else//They didn't give us an absolute path
		{		
			//we then have to check for whether or not the user added ".exe" or not
			//we have to wordSplit() and iterate through words because we don't know where the '.' is
	
			test = wordSplit(test, words[0], ".");

			if(test[1]==NULL){//then they did not input a .exe therefore we have to cancatinate it ourselves
				exeName2 = malloc(strlen(exeName) * sizeof(char));
				strcpy(exeName2, exeName);
				strcat(exeName, ".exe");
			} else if(strcmp(test[1],"exe")==0){//we have to check if test[1] is actually "exe" and not some shenanigans
				exeName2 = malloc((strlen(exeName) - 3) * sizeof(char));
				strncpy(exeName2, exeName, strlen(exeName) - 4);
				strncpy(exeName2 + strlen(exeName) - 4, exeName + strlen(exeName), 1);	//Copy the \0 at the end
			} else{//something went wrong
				printf("Invalid command. Please do not give any commands with an extension other than .exe\n");
				continue;
			}

			//searching in all the paths for this exe
			for(iter = 0; iter < 256 && !found; ++iter)
			{
				int iter2 = 0;
				if(paths[iter] == NULL)break;
				folderName = paths[iter];
				d = opendir(folderName);
				if(d == NULL)
				{ 
					continue;
				}
				while(de = readdir(d))
				{
					if(strcmp(de->d_name, exeName) == 0)
					{	//File found!
						pathName = malloc(strlen(folderName) + strlen(exeName) + sizeof(char));
						strcpy(pathName, folderName);
						strcat(pathName, "/");
						strcat(pathName, exeName);
						found = TRUE;
						break;
					}
					else if(strcmp(de->d_name, exeName2) == 0)
					{	//File found!
						pathName = malloc(strlen(folderName) + strlen(exeName2) + sizeof(char));
						strcpy(pathName, folderName);
						strcat(pathName, "/");
						strcat(pathName, exeName2);
						found = TRUE;
						break;
					}
				}
				closedir(d);
			}
		}

		if(!found)
		{	//The process was not found, so don't attempt to fork()
			printf("Process '%s' not found.\n", exeName);
			continue;
		}	


		processID = fork();
		if(processID == -1)
		{
			return 1;
		}
		else if(processID == 0)
		{
			words[0] = pathName;
			execv(pathName, words);
		}
		else
		{
			int i;
			wait(&processStatus);
		}
	}
}

char** wordSplit(char** target, char* line, char* delimiters)
{
	char** phrase;	//maximum 256 characters, so maximum 256 words
	char *linecpy, *word, *temp, temp2[1];
	int lastPos = -1, pos = 0, arrSize = 0;
	int currPos;
	int i;
	linecpy = malloc(strlen(line) * sizeof(char));
	strcpy(linecpy, line);
	phrase = malloc(256 * sizeof(char));
	temp = strtok(linecpy, delimiters);
	phrase[0] = malloc(strlen(temp) * sizeof(char));
	strcpy(phrase[0], temp);
	if(phrase[0] == NULL) 
	{
		target = phrase;
		return target;
	}//Nothing to test, we're null-testing this return case in any use.
	for(currPos = 1; currPos < 256; ++currPos)
	{
		temp = strtok(NULL, delimiters);
		if(temp == NULL)
		{
			phrase[currPos] = NULL;
			break;
		}
		phrase[currPos] = malloc(strlen(temp) * sizeof(char));
		strcpy(phrase[currPos], temp);
	}
	target = phrase;
	return target;
}
